home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / boot / netBoot.OpenProm / RCS / inet.c,v < prev    next >
Text File  |  1991-01-13  |  26KB  |  1,133 lines

  1. head     1.3;
  2. branch   ;
  3. access   ;
  4. symbols  ;
  5. locks    ; strict;
  6. comment  @ * @;
  7.  
  8.  
  9. 1.3
  10. date     91.01.13.02.43.07;  author dlong;  state Exp;
  11. branches ;
  12. next     1.2;
  13.  
  14. 1.2
  15. date     90.10.10.15.16.16;  author mendel;  state Exp;
  16. branches ;
  17. next     1.1;
  18.  
  19. 1.1
  20. date     89.06.20.10.32.00;  author mendel;  state Exp;
  21. branches ;
  22. next     ;
  23.  
  24.  
  25. desc
  26. @@
  27.  
  28.  
  29. 1.3
  30. log
  31. @converted to use Sprite header files instead of Sun.
  32. @
  33. text
  34. @#ifndef lint
  35. static    char sccsid[] = "@@(#)inet.c    1.12 88/02/08    Copyr 1986 Sun Micro";
  36. #endif
  37.  
  38. /*
  39.  * Copyright (c) 1986 by Sun Microsystems, Inc.
  40.  */
  41.  
  42. /*
  43.  * Standalone IP send and receive - specific to Ethernet
  44.  * Includes ARP and Reverse ARP
  45.  */
  46. #include "boot.h"
  47. #include "sainet.h"
  48. #include "idprom.h"
  49.  
  50. Net_EtherAddress etherbroadcastaddr = { 
  51.     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  52. };
  53.  
  54.  
  55. #define WAITCNT    2    /* 4 seconds before bitching about arp/revarp */
  56.  
  57. /*
  58.  * Fetch our Ethernet address from the ID prom
  59.  */
  60. myetheraddr(ea)
  61.     Net_EtherAddress *ea;
  62. {
  63.     struct idprom id;
  64.  
  65.     if (idprom(IDFORM_1, &id) != IDFORM_1) {
  66.         printf("ERROR: missing or invalid ID prom\n");
  67.         return;
  68.     }
  69.     *ea = *(Net_EtherAddress *)id.id_ether;
  70. }
  71.  
  72. /*
  73.  * Initialize IP state
  74.  * Find out our Ethernet address and call Reverse ARP
  75.  * to find out our Internet address
  76.  * Set the ARP cache to the broadcast host
  77.  */
  78. inet_init(fileId, sain, tmpbuf)
  79.     register void *fileId;
  80.     register struct sainet *sain;
  81.     char *tmpbuf;
  82. {
  83.     myetheraddr(&sain->myEther);
  84.     bzero((caddr_t)&sain->myAddr, sizeof(Net_InetAddress));
  85.     bzero((caddr_t)&sain->hisAddr, sizeof(Net_InetAddress));
  86.     sain->hisEther = etherbroadcastaddr;
  87.     revarp(fileId, sain, tmpbuf);
  88. }
  89.  
  90.  
  91. /*
  92.  * Output an IP packet
  93.  * Cause ARP to be invoked if necessary
  94.  */
  95. ip_output(fileId, buf, len, sain, tmpbuf)
  96.     register void *fileId;
  97.     caddr_t buf, tmpbuf;
  98.     short len;
  99.     register struct sainet *sain;
  100. {
  101.     register Net_EtherHdr *eh;
  102.     register Net_IPHeader *ip;
  103.  
  104.     eh = (Net_EtherHdr *)buf;
  105.     ip = (Net_IPHeader *)(buf + sizeof(Net_EtherHdr));
  106.     if (!inet_cmp(ip->dest, sain->hisAddr)) {
  107.         inet_copy(sain->hisAddr, ip->dest);
  108.         arp(fileId, sain, tmpbuf);
  109.     }
  110.     eh->type = NET_ETHER_IP;
  111.     eh->source = sain->myEther;
  112.     eh->destination = sain->hisEther;
  113.     /* checksum the packet */
  114.     ip->checksum = 0;
  115.     ip->checksum = ipcksum((caddr_t)ip, sizeof (Net_IPHeader));
  116.     if (len < NET_ETHER_MIN_BYTES) {
  117.         len = NET_ETHER_MIN_BYTES;
  118.     }
  119.     return !xmit_packet(fileId, buf, len);
  120. }
  121.  
  122. /*
  123.  * Check incoming packets for IP packets
  124.  * addressed to us. Also, respond to ARP packets
  125.  * that wish to know about us.
  126.  * Returns a length for any IP packet addressed to us, 0 otherwise.
  127.  */
  128. ip_input(fileId, buf, sain)
  129.     register void *fileId;
  130.     caddr_t buf;
  131.     register struct sainet *sain;
  132. {
  133.     register short len;
  134.     register Net_EtherHdr *eh;
  135.     register Net_IPHeader *ip;
  136.     register Net_ArpPacket *ea;
  137.  
  138.     len = poll_packet(fileId, buf);
  139.     eh = (Net_EtherHdr *)buf;
  140.     if (eh->type == NET_ETHER_IP &&
  141.         len >= sizeof(Net_EtherHdr)+sizeof(Net_IPHeader)) {
  142.         ip = (Net_IPHeader *)(buf + sizeof(Net_EtherHdr));
  143. #ifdef NOREVARP
  144.         if ((sain->hisAddr.s_addr & 0xFF000000) == 0 &&
  145.             NET_ETHER_COMPARE(etherbroadcastaddr,
  146.             eh->destination) == 0 &&
  147.             (in_broadaddr(sain->hisAddr) ||
  148.             in_lnaof(ip->source) == in_lnaof(sain->hisAddr))) {
  149.             sain->myAddr = ip->dest;
  150.             sain->hisAddr = ip->source;
  151.             sain->hisEther = eh->source;
  152.         }
  153. #endif
  154.         if (!inet_cmp(ip->dest, sain->myAddr))
  155.             return (0);
  156.         return (len);
  157.     }
  158.     if (eh->type == NET_ETHER_ARP &&
  159.         len >= sizeof(Net_EtherHdr) + sizeof(Net_ArpPacket)) {
  160.         ea = (Net_ArpPacket *)buf;
  161.         if (ea->protocolType != NET_ETHER_IP)
  162.             return (0);
  163.         if (inet_cmp(ea->senderProtAddr, sain->hisAddr)) {
  164.             sain->hisEther = ea->senderEtherAddr;
  165.         }
  166.         if (ea->opcode == NET_ARP_REQUEST &&
  167.             inet_cmp(ea->targetProtAddr, sain->myAddr)) {
  168.             ea->opcode = NET_ARP_REPLY;
  169.             eh->destination = ea->senderEtherAddr;
  170.             eh->source = sain->myEther;
  171.             ea->targetEtherAddr = ea->senderEtherAddr;
  172.             inet_copy(ea->targetProtAddr, ea->senderProtAddr);
  173.             ea->senderEtherAddr = sain->myEther;
  174.             inet_copy(ea->senderProtAddr, sain->myAddr);
  175.             (void) xmit_packet(fileId, buf, 
  176.                 sizeof(Net_ArpPacket));
  177.         }
  178.         return (0);
  179.     }
  180.     return (0);
  181. }
  182.  
  183. /*
  184.  * arp
  185.  * Broadcasts to determine Ethernet address given IP address
  186.  * See RFC 826
  187.  */
  188. arp(fileId, sain, tmpbuf)
  189.     register void *fileId;
  190.     register struct sainet *sain;
  191.     char *tmpbuf;
  192. {
  193.     Net_ArpPacket out;
  194.  
  195.     if (in_broadaddr(sain->hisAddr)
  196. #ifdef NOREVARP
  197.         || (sain->hisAddr.s_addr & 0xFF000000) == 0
  198. #endif
  199.         ) {
  200.         sain->hisEther = etherbroadcastaddr;
  201.         return;
  202.     }
  203.     out.header.type = NET_ETHER_ARP;
  204.     out.opcode = NET_ARP_REQUEST;
  205.     out.targetEtherAddr = etherbroadcastaddr;    /* what we want */
  206.     out.targetProtAddr = sain->hisAddr;
  207.     comarp(fileId, sain, &out, tmpbuf);
  208. }
  209.  
  210. /*
  211.  * Reverse ARP client side
  212.  * Determine our Internet address given our Ethernet address
  213.  * See RFC 903
  214.  */
  215. revarp(fileId, sain, tmpbuf)
  216.     register void *fileId;
  217.     register struct sainet *sain;
  218.     char *tmpbuf;
  219. {
  220.     Net_ArpPacket out;
  221.  
  222. #ifdef NOREVARP
  223.     bzero((caddr_t)&sain->myAddr, sizeof(Net_InetAddress));
  224.     bcopy((caddr_t)&sain->myEther.ether_addr_octet[3],
  225.         (caddr_t)(&sain->myAddr)+1, 3);
  226. #else
  227.     out.header.type = NET_ETHER_REVARP;
  228.     out.opcode = NET_RARP_REQUEST;
  229.     out.targetEtherAddr = sain->myEther;
  230.     /* What we want to find out... */
  231.     bzero((caddr_t)&out.targetProtAddr, sizeof(Net_InetAddress));
  232.     comarp(fileId, sain, &out, tmpbuf);
  233. #endif
  234. }
  235.  
  236. /*
  237.  * Common ARP code 
  238.  * Broadcast the packet and wait for the right response.
  239.  * Fills in *sain with the results
  240.  */
  241. comarp(fileId, sain, out, tmpbuf)
  242.     register void *fileId;
  243.     register struct sainet *sain;
  244.     register Net_ArpPacket *out;
  245.     char *tmpbuf;
  246. {
  247.     register Net_ArpPacket *in = (Net_ArpPacket *)tmpbuf;
  248.     register int e, count, time, feedback,len, delay = 2;
  249.     char    *ind = "-\\|/";
  250.  
  251.     out->header.destination = etherbroadcastaddr;
  252.     out->header.source = sain->myEther;
  253.     out->hardwareType =  NET_ARP_TYPE_ETHER;
  254.     out->protocolType = NET_ETHER_IP;
  255.     out->hardwareAddrLen = sizeof(Net_EtherAddress);
  256.     out->protocolAddrLen = sizeof(Net_InetAddress);
  257.     out->senderEtherAddr = sain->myEther;
  258.     out->senderProtAddr = sain->myAddr;
  259.     feedback = 0;
  260.  
  261.     for (count=0; ; count++) {
  262.         if (count == WAITCNT) {
  263.             if (out->opcode == NET_ARP_REQUEST) {
  264.                 printf("\nRequesting Ethernet address for ");
  265.                 inet_print(&out->targetProtAddr);
  266.             } else {
  267.                 printf("\nRequesting Internet address for ");
  268.                 ether_print(&out->targetEtherAddr);
  269.             }
  270.         }
  271.         e = xmit_packet(fileId, (caddr_t)out, sizeof *out);
  272.         if (!e)
  273.             printf("X\b");
  274.         else
  275.             printf("%c\b", ind[feedback++ % 4]); /* Show activity */
  276.  
  277.         time = millitime() + (delay * 1000);    /* broadcast delay */
  278.         while (millitime() <= time) {
  279.             len = poll_packet(fileId, tmpbuf);
  280.             if (len < sizeof(Net_ArpPacket))
  281.                 continue;
  282.             if (in->protocolType != NET_ETHER_IP)
  283.                 continue;
  284.             if (out->opcode == NET_ARP_REQUEST) {
  285.                 if (in->header.type != NET_ETHER_ARP)
  286.                     continue;
  287.                 if (in->opcode != NET_ARP_REPLY)
  288.                     continue;
  289.                 if (in->senderProtAddr != out->targetProtAddr)
  290.                     continue;
  291.                 if (count >= WAITCNT) {
  292.                     printf("Found at ");
  293.                     ether_print(&in->senderEtherAddr);
  294.                 }
  295.                 sain->hisEther = in->senderEtherAddr;
  296.                 return;
  297.             } else {        /* Reverse ARP */
  298.                 if (in->header.type != NET_ETHER_REVARP)
  299.                     continue;
  300.                 if (in->opcode != NET_RARP_REPLY)
  301.                     continue;
  302.                 if (NET_ETHER_COMPARE(in->targetEtherAddr,
  303.                     out->targetEtherAddr) == 0)
  304.                     continue;
  305.  
  306.                 if (count >= WAITCNT) {
  307.                     printf("Internet address is ");
  308.                     inet_print(&in->targetProtAddr);
  309.                 }
  310.                 inet_copy(sain->myAddr, in->targetProtAddr);
  311.                 /*
  312.                  * short circuit first ARP
  313.                  */
  314.                 inet_copy(sain->hisAddr, in->senderProtAddr);
  315.                 sain->hisEther = in->senderEtherAddr;
  316.                 return;
  317.             }
  318.         }
  319.  
  320.         delay = delay * 2;    /* Double the request delay */
  321.         if (delay > 64)        /* maximum delay is 64 seconds */
  322.             delay = 64;
  323.  
  324.         reset(fileId);
  325.     }
  326.     /* NOTREACHED */
  327. }
  328.  
  329. /*
  330.  * Return the host portion of an internet address.
  331.  */
  332. in_lnaof(in)
  333.     Net_InetAddress in;
  334. {
  335.     if (NET_INET_CLASS_A_ADDR(in))
  336.         return ((in)&NET_INET_CLASS_A_HOST_MASK);
  337.     else if (NET_INET_CLASS_B_ADDR(in))
  338.         return ((in)&NET_INET_CLASS_B_HOST_MASK);
  339.     else
  340.         return ((in)&NET_INET_CLASS_C_HOST_MASK);
  341. }
  342.  
  343. /*
  344.  * Test for broadcast IP address
  345.  */
  346. in_broadaddr(in)
  347.     Net_InetAddress in;
  348. {
  349.     if (NET_INET_CLASS_A_ADDR(in)) {
  350.         in &= NET_INET_CLASS_A_HOST_MASK;
  351.         return (in == 0 || in == 0xFFFFFF);
  352.     } else if (NET_INET_CLASS_B_ADDR(in)) {
  353.         in &= NET_INET_CLASS_B_HOST_MASK;
  354.         return (in == 0 || in == 0xFFFF);
  355.     } else if (NET_INET_CLASS_C_ADDR(in)) {
  356.         in &= NET_INET_CLASS_C_HOST_MASK;
  357.         return (in == 0 || in == 0xFF);
  358.     } else
  359.         return (0);
  360.     /*NOTREACHED*/
  361. }
  362.  
  363. /*
  364.  * Compute one's complement checksum
  365.  * for IP packet headers 
  366.  */
  367. ipcksum(cp, count)
  368.     caddr_t    cp;
  369.     register unsigned short    count;
  370. {
  371.     register unsigned short    *sp = (unsigned short *)cp;
  372.     register unsigned long    sum = 0;
  373.     register unsigned long    oneword = 0x00010000;
  374.  
  375.     count >>= 1;
  376.     while (count--) {
  377.         sum += *sp++;
  378.         if (sum >= oneword) {        /* Wrap carries into low bit */
  379.             sum -= oneword;
  380.             sum++;
  381.         }
  382.     }
  383.     return (~sum);
  384. }
  385.  
  386. inet_print(p)
  387.     Net_InetAddress *p;
  388. {
  389.     Net_InetAddress s;
  390.  
  391.     inet_copy(s, *p);
  392.     printf("%d.%d.%d.%d\n",
  393.         (s >> 24) & 0xff,
  394.         (s >> 16) & 0xff,
  395.         (s >>  8) & 0xff,
  396.         s & 0xff);
  397. }
  398.  
  399. ether_print(ea)
  400.     Net_EtherAddress *ea;
  401. {
  402.     printf("%x:%x:%x:%x:%x:%x\n",
  403.         NET_ETHER_ADDR_BYTE1(*ea),
  404.         NET_ETHER_ADDR_BYTE2(*ea),
  405.         NET_ETHER_ADDR_BYTE3(*ea),
  406.         NET_ETHER_ADDR_BYTE4(*ea),
  407.         NET_ETHER_ADDR_BYTE5(*ea),
  408.         NET_ETHER_ADDR_BYTE6(*ea));
  409. }
  410. @
  411.  
  412.  
  413. 1.2
  414. log
  415. @*** empty log message ***
  416. @
  417. text
  418. @a12 1
  419. #include "machparam.h"
  420. a13 8
  421. #include "saio.h"
  422. #include "socket.h"
  423. #include "if.h"
  424. #include "if_arp.h"
  425. #include "in.h"
  426. #include "if_ether.h"
  427. #include "in_systm.h"
  428. #include "ip.h"
  429. a14 1
  430. #include "sunromvec.h"
  431. d17 1
  432. a17 3
  433. #define millitime() (*romp->v_nmiclock)
  434.  
  435. struct ether_addr etherbroadcastaddr = { 
  436. a20 6
  437. struct arp_packet {
  438.     struct ether_header    arp_eh;
  439.     struct ether_arp    arp_ea;
  440. #define    used_size (sizeof (struct ether_header)+sizeof(struct ether_arp))
  441.     char    filler[ETHERMIN - sizeof(struct ether_arp)];
  442. };
  443. d28 1
  444. a28 1
  445.     struct ether_addr *ea;
  446. d36 1
  447. a36 1
  448.     *ea = *(struct ether_addr *)id.id_ether;
  449. d45 2
  450. a46 2
  451. inet_init(sip, sain, tmpbuf)
  452.     register struct saioreq *sip;
  453. d50 5
  454. a54 5
  455.     myetheraddr(&sain->sain_myether);
  456.     bzero((caddr_t)&sain->sain_myaddr, sizeof(struct in_addr));
  457.     bzero((caddr_t)&sain->sain_hisaddr, sizeof(struct in_addr));
  458.     sain->sain_hisether = etherbroadcastaddr;
  459.     revarp(sip, sain, tmpbuf);
  460. d62 2
  461. a63 2
  462. ip_output(sip, buf, len, sain, tmpbuf)
  463.     register struct saioreq *sip;
  464. d68 2
  465. a69 2
  466.     register struct ether_header *eh;
  467.     register struct ip *ip;
  468. d71 5
  469. a75 9
  470.     eh = (struct ether_header *)buf;
  471.     ip = (struct ip *)(buf + sizeof(struct ether_header));
  472.     if (bcmp((caddr_t)&ip->ip_dst,
  473.         (caddr_t)&sain->sain_hisaddr,
  474.         sizeof(struct in_addr)) != 0) {
  475.             bcopy((caddr_t)&ip->ip_dst,
  476.                 (caddr_t)&sain->sain_hisaddr,
  477.                 sizeof (struct in_addr));
  478.             arp(sip, sain, tmpbuf);
  479. d77 3
  480. a79 3
  481.     eh->ether_type = ETHERTYPE_IP;
  482.     eh->ether_shost = sain->sain_myether;
  483.     eh->ether_dhost = sain->sain_hisether;
  484. d81 4
  485. a84 4
  486.     ip->ip_sum = 0;
  487.     ip->ip_sum = ipcksum((caddr_t)ip, sizeof (struct ip));
  488.     if (len < ETHERMIN + sizeof(struct ether_header)) {
  489.         len = ETHERMIN+sizeof(struct ether_header);
  490. d86 1
  491. a86 1
  492.     return (*sip->si_sif->sif_xmit)(sip->si_devdata, buf, len);
  493. d95 2
  494. a96 2
  495. ip_input(sip, buf, sain)
  496.     register struct saioreq *sip;
  497. d101 3
  498. a103 3
  499.     register struct ether_header *eh;
  500.     register struct ip *ip;
  501.     register struct ether_arp *ea;
  502. d105 5
  503. a109 5
  504.     len = (*sip->si_sif->sif_poll)(sip->si_devdata, buf);
  505.     eh = (struct ether_header *)buf;
  506.     if (eh->ether_type == ETHERTYPE_IP &&
  507.         len >= sizeof(struct ether_header)+sizeof(struct ip)) {
  508.         ip = (struct ip *)(buf + sizeof(struct ether_header));
  509. d111 8
  510. a118 9
  511.         if ((sain->sain_hisaddr.s_addr & 0xFF000000) == 0 &&
  512.             bcmp((caddr_t)ðerbroadcastaddr,
  513.             (caddr_t)&eh->ether_dhost,
  514.             sizeof(struct ether_addr)) != 0 &&
  515.             (in_broadaddr(sain->sain_hisaddr) ||
  516.             in_lnaof(ip->ip_src) == in_lnaof(sain->sain_hisaddr))) {
  517.             sain->sain_myaddr = ip->ip_dst;
  518.             sain->sain_hisaddr = ip->ip_src;
  519.             sain->sain_hisether = eh->ether_shost;
  520. d121 1
  521. a121 3
  522.         if (bcmp((caddr_t)&ip->ip_dst,
  523.             (caddr_t)&sain->sain_myaddr,
  524.             sizeof(struct in_addr)) != 0)
  525. d125 4
  526. a128 4
  527.     if (eh->ether_type == ETHERTYPE_ARP &&
  528.         len >= sizeof(struct ether_header) + sizeof(struct ether_arp)) {
  529.         ea = (struct ether_arp *)(buf + sizeof(struct ether_header));
  530.         if (ea->arp_pro != ETHERTYPE_IP)
  531. d130 2
  532. a131 21
  533.         if (bcmp((caddr_t)ea->arp_spa,
  534.             (caddr_t)&sain->sain_hisaddr,
  535.             sizeof(struct in_addr)) == 0)
  536.             sain->sain_hisether = ea->arp_sha;
  537.         if (ea->arp_op == ARPOP_REQUEST &&
  538.             (bcmp((caddr_t)ea->arp_tpa,
  539.               (caddr_t)&sain->sain_myaddr,
  540.               sizeof(struct in_addr)) == 0)) {
  541.             ea->arp_op = ARPOP_REPLY;
  542.             eh->ether_dhost = ea->arp_sha;
  543.             eh->ether_shost = sain->sain_myether;
  544.             ea->arp_tha = ea->arp_sha;
  545.             bcopy((caddr_t)ea->arp_spa,
  546.                 (caddr_t)ea->arp_tpa,
  547.                 sizeof(ea->arp_tpa));
  548.             ea->arp_sha = sain->sain_myether;
  549.             bcopy((caddr_t)&sain->sain_myaddr,
  550.                 (caddr_t)ea->arp_spa,
  551.                 sizeof(ea->arp_spa));
  552.             (*sip->si_sif->sif_xmit)(sip->si_devdata, buf, 
  553.                         sizeof(struct arp_packet));
  554. d133 12
  555. d155 2
  556. a156 2
  557. arp(sip, sain, tmpbuf)
  558.     register struct saioreq *sip;
  559. d160 1
  560. a160 1
  561.     struct arp_packet out;
  562. d162 1
  563. a162 1
  564.     if (in_broadaddr(sain->sain_hisaddr)
  565. d164 1
  566. a164 1
  567.         || (sain->sain_hisaddr.s_addr & 0xFF000000) == 0
  568. d167 1
  569. a167 1
  570.         sain->sain_hisether = etherbroadcastaddr;
  571. d170 5
  572. a174 7
  573.     out.arp_eh.ether_type = ETHERTYPE_ARP;
  574.     out.arp_ea.arp_op = ARPOP_REQUEST;
  575.     out.arp_ea.arp_tha = etherbroadcastaddr;    /* what we want */
  576.     bcopy((caddr_t)&sain->sain_hisaddr,
  577.         (caddr_t)out.arp_ea.arp_tpa,
  578.         sizeof(sain->sain_hisaddr));
  579.     comarp(sip, sain, &out, tmpbuf);
  580. d182 2
  581. a183 2
  582. revarp(sip, sain, tmpbuf)
  583.     register struct saioreq *sip;
  584. d187 1
  585. a187 1
  586.     struct arp_packet out;
  587. d190 3
  588. a192 3
  589.     bzero((caddr_t)&sain->sain_myaddr, sizeof(struct in_addr));
  590.     bcopy((caddr_t)&sain->sain_myether.ether_addr_octet[3],
  591.         (caddr_t)(&sain->sain_myaddr)+1, 3);
  592. d194 3
  593. a196 3
  594.     out.arp_eh.ether_type = ETHERTYPE_REVARP;
  595.     out.arp_ea.arp_op = REVARP_REQUEST;
  596.     out.arp_ea.arp_tha = sain->sain_myether;
  597. d198 2
  598. a199 2
  599.     bzero(out.arp_ea.arp_tpa, sizeof(struct in_addr));
  600.     comarp(sip, sain, &out, tmpbuf);
  601. d208 2
  602. a209 2
  603. comarp(sip, sain, out, tmpbuf)
  604.     register struct saioreq *sip;
  605. d211 1
  606. a211 1
  607.     register struct arp_packet *out;
  608. d214 1
  609. a214 1
  610.     register struct arp_packet *in = (struct arp_packet *)tmpbuf;
  611. d216 1
  612. a216 2
  613.     char    *ind = "-\|/";
  614.     struct in_addr tmp_ia;
  615. d218 8
  616. a225 10
  617.     out->arp_eh.ether_dhost = etherbroadcastaddr;
  618.     out->arp_eh.ether_shost = sain->sain_myether;
  619.     out->arp_ea.arp_hrd =  ARPHRD_ETHER;
  620.     out->arp_ea.arp_pro = ETHERTYPE_IP;
  621.     out->arp_ea.arp_hln = sizeof(struct ether_addr);
  622.     out->arp_ea.arp_pln = sizeof(struct in_addr);
  623.     out->arp_ea.arp_sha = sain->sain_myether;
  624.     bcopy((caddr_t)&sain->sain_myaddr,
  625.         (caddr_t)out->arp_ea.arp_spa, 
  626.         sizeof(out->arp_ea.arp_spa));
  627. d230 1
  628. a230 1
  629.             if (out->arp_ea.arp_op == ARPOP_REQUEST) {
  630. d232 1
  631. a232 3
  632.                 bcopy((caddr_t)out->arp_ea.arp_tpa,
  633.                     (caddr_t)&tmp_ia, sizeof(tmp_ia));
  634.                 inet_print(tmp_ia);
  635. d235 1
  636. a235 1
  637.                 ether_print(&out->arp_ea.arp_tha);
  638. d238 2
  639. a239 3
  640.         e = (*sip->si_sif->sif_xmit)(sip->si_devdata, (caddr_t)out,
  641.             sizeof *out);
  642.         if (e)
  643. d246 2
  644. a247 2
  645.             len = (*sip->si_sif->sif_poll)(sip->si_devdata, tmpbuf);
  646.             if (len < used_size)
  647. d249 1
  648. a249 1
  649.             if (in->arp_ea.arp_pro != ETHERTYPE_IP)
  650. d251 2
  651. a252 2
  652.             if (out->arp_ea.arp_op == ARPOP_REQUEST) {
  653.                 if (in->arp_eh.ether_type != ETHERTYPE_ARP)
  654. d254 1
  655. a254 1
  656.                 if (in->arp_ea.arp_op != ARPOP_REPLY)
  657. d256 1
  658. a256 3
  659.                 if (bcmp((caddr_t)in->arp_ea.arp_spa,
  660.                     (caddr_t)out->arp_ea.arp_tpa,
  661.                      sizeof(struct in_addr)) != 0)
  662. d260 1
  663. a260 1
  664.                     ether_print(&in->arp_ea.arp_sha);
  665. d262 1
  666. a262 1
  667.                 sain->sain_hisether = in->arp_ea.arp_sha;
  668. d265 1
  669. a265 1
  670.                 if (in->arp_eh.ether_type !=ETHERTYPE_REVARP)
  671. d267 1
  672. a267 1
  673.                 if (in->arp_ea.arp_op != REVARP_REPLY)
  674. d269 2
  675. a270 3
  676.                 if (bcmp((caddr_t)&in->arp_ea.arp_tha,
  677.                     (caddr_t)&out->arp_ea.arp_tha, 
  678.                     sizeof (struct ether_addr)) != 0)
  679. d275 1
  680. a275 3
  681.                     bcopy((caddr_t)in->arp_ea.arp_tpa,
  682.                         (caddr_t)&tmp_ia, sizeof(tmp_ia));
  683.                     inet_print(tmp_ia);
  684. d277 1
  685. a277 3
  686.                 bcopy((caddr_t)in->arp_ea.arp_tpa, 
  687.                     (caddr_t)&sain->sain_myaddr,
  688.                     sizeof(sain->sain_myaddr));
  689. d281 2
  690. a282 4
  691.                 bcopy((caddr_t)in->arp_ea.arp_spa, 
  692.                     (caddr_t)&sain->sain_hisaddr,
  693.                     sizeof(sain->sain_hisaddr));
  694.                 sain->sain_hisether = in->arp_ea.arp_sha;
  695. d291 1
  696. a291 1
  697.         (*sip->si_sif->sif_reset)(sip->si_devdata);
  698. d300 1
  699. a300 1
  700.     struct in_addr in;
  701. d302 4
  702. a305 6
  703.     register u_long i = ntohl(in.s_addr);
  704.  
  705.     if (IN_CLASSA(i))
  706.         return ((i)&IN_CLASSA_HOST);
  707.     else if (IN_CLASSB(i))
  708.         return ((i)&IN_CLASSB_HOST);
  709. d307 1
  710. a307 1
  711.         return ((i)&IN_CLASSC_HOST);
  712. d314 1
  713. a314 1
  714.     struct in_addr in;
  715. d316 9
  716. a324 11
  717.     register u_long i = ntohl(in.s_addr);
  718.  
  719.     if (IN_CLASSA(i)) {
  720.         i &= IN_CLASSA_HOST;
  721.         return (i == 0 || i == 0xFFFFFF);
  722.     } else if (IN_CLASSB(i)) {
  723.         i &= IN_CLASSB_HOST;
  724.         return (i == 0 || i == 0xFFFF);
  725.     } else if (IN_CLASSC(i)) {
  726.         i &= IN_CLASSC_HOST;
  727.         return (i == 0 || i == 0xFF);
  728. d353 2
  729. a354 2
  730. inet_print(s)
  731.     struct in_addr s;
  732. d356 3
  733. d360 4
  734. a363 4
  735.         (s.s_addr >> 24) & 0xff,
  736.         (s.s_addr >> 16) & 0xff,
  737.         (s.s_addr >>  8) & 0xff,
  738.         s.s_addr & 0xff);
  739. d367 1
  740. a367 1
  741.     struct ether_addr *ea;
  742. d369 7
  743. a375 3
  744.     register u_char *p = &ea->ether_addr_octet[0];
  745.  
  746.     printf("%x:%x:%x:%x:%x:%x\n", p[0], p[1], p[2], p[3], p[4], p[5]);
  747. @
  748.  
  749.  
  750. 1.1
  751. log
  752. @Initial revision
  753. @
  754. text
  755. @d1 4
  756. a5 3
  757.  * inet.c
  758.  *
  759.  * @@(#)inet.c 1.7 88/02/08 Copyr 1986 Sun Micro
  760. d13 13
  761. a25 10
  762. #include "../dev/saio.h"
  763. #include "../h/socket.h"
  764. #include "../dev/if.h"
  765. #include "../h/in.h"
  766. #include "../dev/if_ether.h"
  767. #include "../h/in_systm.h"
  768. #include "../h/ip.h"
  769. #include "../h/sainet.h"
  770. #include "../h/sunromvec.h"
  771. #include "../h/idprom.h"
  772. d40 2
  773. a41 2
  774. #define WAITCNT    2                /* 4 sec. wait for arp/revarp */
  775.  
  776. d43 1
  777. a43 6
  778.  * Description: Fetches our Ethernet address from the ID prom
  779.  *
  780.  * Synopsis:    status = myetheraddr(ea)
  781.  *        status    :(null)
  782.  *        ea    :(char *) pointer to ethernet address structure
  783.  * Routines:    idprom, printf 
  784. d56 1
  785. a56 1
  786.  
  787. d58 4
  788. a61 13
  789.  * Description: Initialize IP state
  790.  *
  791.  *         Find out our Ethernet address and call Reverse ARP.
  792.  *         To find out our Internet address,
  793.  *         set the ARP cache to the broadcast host
  794.  *
  795.  * Synopsis:    status = inet_init(sip, sain, tmpbuf)
  796.  *        status    :(null)
  797.  *        sip    :(char *) pointer to saioreq structure
  798.  *        sain    :(char *) pointer to sainet  structure
  799.  *        tmpbuf    :(char *) pointer to temporary buffer space
  800.  *
  801.  * Routines:    myetheraddr, revarp
  802. d68 3
  803. a70 3
  804.     myetheraddr(&sain->sain_myether);    /* ethernet addr from IDPROM */
  805.     sain->sain_hisaddr.s_addr = 0;        /* clear address */
  806.                         /* broadcast msg. */
  807. d72 1
  808. a72 1
  809.     revarp(sip, sain, tmpbuf);        /* deter. internet address */
  810. d74 2
  811. a75 1
  812.  
  813. d77 2
  814. a78 14
  815.  * Description: Output an IP packet
  816.  *
  817.  *         Cause ARP to be invoked if necessary
  818.  *
  819.  * Synopsis:    status = ip_output(sip, buf, len, sain, tmpbuf)
  820.  *        status    :(null)
  821.  *        sip    :(char *) pointer to saioreq structure
  822.  *        buf    :(char *) address pointer to buffer
  823.  *        len    :(short)  length of IP packet
  824.  *        sain    :(char *) pointer to sainet  structure
  825.  *        tmpbuf    :(char *) pointer to temporary buffer space
  826.  *
  827.  * Routines:    arp, ipcksum, sif_xmit
  828.  *
  829. a88 1
  830.                         /* construct header */
  831. a89 2
  832.                         /* check destination addr */
  833.  
  834. d91 7
  835. a97 3
  836.     if (ip->ip_dst.s_addr != sain->sain_hisaddr.s_addr) {
  837.         sain->sain_hisaddr.s_addr = ip->ip_dst.s_addr;
  838.         arp(sip, sain, tmpbuf);
  839. d99 1
  840. a99 1
  841.     eh->ether_type = ETHERPUP_IPTYPE;
  842. d102 1
  843. a102 1
  844.                         /* checksum the packet */
  845. d105 1
  846. a105 3
  847.  
  848.                         /* set length of packet */
  849.     if (len < ETHERMIN+sizeof(struct ether_header))
  850. d107 1
  851. a107 3
  852.  
  853.                         /* transmit */
  854.  
  855. d110 1
  856. a110 1
  857.  
  858. d112 4
  859. a115 11
  860.  * Description: Check incoming packets for IP packets addressed to us.
  861.  *
  862.  *        Also, respond to ARP packets that wish to know about us.
  863.  *         Returns a length for any IP packet addressed to us, 0 otherwise.
  864.  *
  865.  * Synopsis:    status = ip_input(sip, buf, sain)
  866.  *        sip    :(char *) pointer to saioreq structure
  867.  *        sain    :(char *) pointer to sainet  structure
  868.  *        buf    :(char *) address pointer to buffer space for packet
  869.  *
  870.  * Routine:    sif_poll, sif_xmit
  871. a125 1
  872.                         /* read packet */
  873. a127 2
  874.  
  875.                         /* check header */
  876. d129 1
  877. a129 3
  878.                         /* IP packet */
  879.  
  880.     if (eh->ether_type == ETHERPUP_IPTYPE &&
  881. d132 15
  882. a146 4
  883.  
  884.                         /* make sure it's for me */
  885.  
  886.         if (ip->ip_dst.s_addr != sain->sain_myaddr.s_addr) 
  887. d150 2
  888. a151 4
  889.                         /* ARP packet */
  890.  
  891.     if (eh->ether_type == ETHERPUP_ARPTYPE &&
  892.         len >= sizeof(struct ether_header)+sizeof(struct ether_arp)) {
  893. d153 1
  894. a153 1
  895.         if (ea->arp_pro != ETHERPUP_IPTYPE) 
  896. d155 4
  897. a158 5
  898.         if (arp_spa(ea).s_addr == sain->sain_hisaddr.s_addr)
  899.             sain->sain_hisether = arp_sha(ea);
  900.  
  901.                         /* send ARP reply */
  902.  
  903. d160 3
  904. a162 1
  905.             arp_tpa(ea).s_addr == sain->sain_myaddr.s_addr) {
  906. d164 1
  907. a164 1
  908.             eh->ether_dhost = arp_sha(ea);
  909. d166 8
  910. a173 4
  911.             arp_tha(ea) = arp_sha(ea);
  912.             arp_tpa(ea) = arp_spa(ea);
  913.             arp_sha(ea) = sain->sain_myether;
  914.             arp_spa(ea) = sain->sain_myaddr;
  915. d181 1
  916. a181 1
  917.  
  918. d183 3
  919. a185 10
  920.  * Description: ARP, Broadcasts to determine Ethernet address given IP address
  921.  *         See RFC 826
  922.  *
  923.  * Synopsis:    status = arp(sip, sain, tmpbuf)
  924.  *        status    :(null)
  925.  *        sip    :(char *) pointer to saioreq structure
  926.  *        sain    :(char *) pointer to sainet  structure
  927.  *        tmpbuf    :(char *) pointer to temporary buffer space
  928.  *
  929.  * Routines:    comarp, in_lnaof 
  930. d193 6
  931. a198 4
  932.                         /* deter. destination, lnaof
  933.                          * gets host portion of addr */ 
  934.     if (in_lnaof(sain->sain_hisaddr) == INADDR_ANY ||
  935.        (in_lnaof(sain->sain_hisaddr) & INADDR1_ANY) == INADDR1_ANY) {
  936. d202 1
  937. a202 2
  938.                         /* set up ARP packet */
  939.     out.arp_eh.ether_type = ETHERPUP_ARPTYPE;
  940. d204 11
  941. a214 17
  942.     arp_tha(&out.arp_ea) = etherbroadcastaddr;    /* what we want */
  943.     arp_tpa(&out.arp_ea).s_addr = sain->sain_hisaddr.s_addr;
  944.  
  945.     comarp(sip, sain, &out, tmpbuf);    /* transmit */
  946. }
  947.  
  948. /*
  949.  * Description: Reverse ARP client side
  950.  *         Determine our Internet address given our Ethernet address
  951.  *         See RFC 903
  952.  *
  953.  * Synopsis:    status = revarp(sip, sain, tmpbuf)
  954.  *        status    :(null)
  955.  *        sip    :(char *) pointer to saioreq structure
  956.  *        sain    :(char *) pointer to sainet  structure
  957.  *        tmpbuf    :(char *) pointer to temporary buffer space
  958.  *
  959. a221 1
  960.                         /* set up ARP packet */
  961. d223 6
  962. a228 1
  963.     out.arp_eh.ether_type = ETHERPUP_REVARPTYPE;
  964. d230 11
  965. a240 19
  966.     arp_tha(&out.arp_ea) = sain->sain_myether;
  967.     arp_tpa(&out.arp_ea).s_addr = 0;    /* what we want to find out */
  968.  
  969.     comarp(sip, sain, &out, tmpbuf);    /* transmit */
  970. }
  971.  
  972. /*
  973.  * Description: Common ARP code 
  974.  *         Broadcast the packet and wait for the right response.
  975.  *         Fills in *sain with the results
  976.  *
  977.  * Synopsis:    status = comarp(sip, sain, out, tmpbuf)
  978.  *        status    :(null)
  979.  *        sip    :(char *) pointer to saioreq structure
  980.  *        sain    :(char *) pointer to sainet  structure
  981.  *        out    :(char *) pointer to ARP packet
  982.  *        tmpbuf    :(char *) pointer to temporary buffer space
  983.  *
  984.  * Routines:    bcmp, ether_print, inet_print, sif_xmit,
  985. d249 3
  986. a251 3
  987.     register int e, count, time, feedback, len, delay = 2;
  988.     char    *ind = "-\\|/";
  989.                         /* fill the header */
  990. d255 2
  991. a256 2
  992.     out->arp_ea.arp_hrd = ARPHRD_ETHER;
  993.     out->arp_ea.arp_pro = ETHERPUP_IPTYPE;
  994. d259 4
  995. a262 2
  996.     arp_sha(&out->arp_ea) = sain->sain_myether;
  997.     arp_spa(&out->arp_ea).s_addr = sain->sain_myaddr.s_addr;
  998. a265 1
  999.                         /* timeout message */
  1000. d268 4
  1001. a271 2
  1002.                 printf("Requesting Ethernet address for ");
  1003.                 inet_print(arp_tpa(&out->arp_ea));
  1004. d273 2
  1005. a274 2
  1006.                 printf("Requesting Internet address for ");
  1007.                 ether_print(&arp_tha(&out->arp_ea));
  1008. a276 2
  1009.                         /* transmit */
  1010.  
  1011. d279 4
  1012. a282 8
  1013.         
  1014. #ifdef SUN3F                          
  1015.                 /* Sun-3/F runs at 20 MHZ */
  1016.                 time = millitime() + (delay * 800);     /* broadcast delay */
  1017. #else
  1018.                 time = millitime() + (delay * 1000);    /* broadcast delay */
  1019. #endif SUN3F
  1020.         printf("%c\b", ind[feedback++ % 4]);    /* Show activity */
  1021. d284 1
  1022. a284 1
  1023.                         /* poll for reply */
  1024. a286 2
  1025.  
  1026.                         /* check length */
  1027. d289 1
  1028. a289 2
  1029.                         /* IP packet, waiting for ARP */
  1030.             if (in->arp_ea.arp_pro != ETHERPUP_IPTYPE)
  1031. a290 1
  1032.                         /* ARP packet */
  1033. d292 1
  1034. a292 1
  1035.                 if (in->arp_eh.ether_type != ETHERPUP_ARPTYPE)
  1036. d296 3
  1037. a298 2
  1038.                 if (arp_spa(&in->arp_ea).s_addr !=
  1039.                     arp_tpa(&out->arp_ea).s_addr)
  1040. a299 3
  1041.  
  1042.                         /* timeout message */
  1043.  
  1044. d302 1
  1045. a302 1
  1046.                     ether_print(&arp_sha(&in->arp_ea));
  1047. d304 1
  1048. a304 1
  1049.                 sain->sain_hisether = arp_sha(&in->arp_ea);
  1050. d307 1
  1051. a307 2
  1052.  
  1053.                 if (in->arp_eh.ether_type !=ETHERPUP_REVARPTYPE)
  1054. d311 3
  1055. a313 3
  1056.                 if (bcmp((caddr_t)&arp_tha(&in->arp_ea),
  1057.                          (caddr_t)&arp_tha(&out->arp_ea), 
  1058.                          sizeof (struct ether_addr)) != 0)
  1059. a314 5
  1060.                         /* print IP address */
  1061.                 printf("Using IP Address ");
  1062.                 inet_print(arp_tpa(&in->arp_ea));
  1063.  
  1064.                         /* short circuit first ARP */
  1065. d316 16
  1066. a331 3
  1067.                 sain->sain_myaddr   = arp_tpa(&in->arp_ea);
  1068.                 sain->sain_hisaddr  = arp_spa(&in->arp_ea);
  1069.                 sain->sain_hisether = arp_sha(&in->arp_ea);
  1070. a334 1
  1071.         delay = delay * 2;        /* Double the request delay */
  1072. d336 2
  1073. a337 1
  1074.         if (delay > 64)            /* max. delay is 64 seconds */
  1075. d339 1
  1076. a339 1
  1077.                         /* reset ethernet */
  1078. d344 1
  1079. a344 1
  1080.  
  1081. d346 1
  1082. a346 7
  1083.  * Description: Return the host portion of an internet address.
  1084.  *
  1085.  * Synopsis:    status = in_lnaof(in)
  1086.  *        status    :       host addr
  1087.  *        in    :(in_addr) pointer to internet address
  1088.  *
  1089.  * Routines:    ntohl
  1090. d360 23
  1091. a382 1
  1092.  
  1093. d384 2
  1094. a385 6
  1095.  * Description: Compute one's complement checksum for IP packet headers 
  1096.  *
  1097.  * Synopsis:    status = ipcksum(cp, count)
  1098.  *        status    :      checksum
  1099.  *        cp    :(char *) pointer to IP packet
  1100.  *        count    :(u_short) length of IP packet
  1101. d405 1
  1102. a405 8
  1103.  
  1104. /*
  1105.  * Description: Prints the internet address
  1106.  *
  1107.  * Synopsis:    status = inet_print(s)
  1108.  *        status    :(null)
  1109.  *        s    :(char *) pointer to internet address
  1110.  */
  1111. d409 6
  1112. a414 4
  1113.     int    len = 2;
  1114.  
  1115.     printf("%d.%d.%d.%d = ", s.S_un.S_un_b.s_b1, s.S_un.S_un_b.s_b2,
  1116.         s.S_un.S_un_b.s_b3, s.S_un.S_un_b.s_b4);
  1117. a415 14
  1118.     printhex(s.S_un.S_un_b.s_b1, len);
  1119.     printhex(s.S_un.S_un_b.s_b2, len);
  1120.     printhex(s.S_un.S_un_b.s_b3, len);
  1121.     printhex(s.S_un.S_un_b.s_b4, len);
  1122.     printf("\n");
  1123. }
  1124.  
  1125. /*
  1126.  * Description: Prints the ethernet address
  1127.  *
  1128.  * Synopsis:    status = ether_print(s)
  1129.  *        status    :(null)
  1130.  *        s    :(char *) pointer to ethernet address
  1131.  */
  1132. @
  1133.